package com.hibox.controller;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hibox.common.annotation.Anonymous;
import com.hibox.common.core.domain.AjaxResult;
import com.hibox.common.core.redis.RedisCache;
import com.hibox.domain.Address;
import com.hibox.domain.Member;
import com.hibox.service.AddressService;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.hibox.service.MemberService;
import com.hibox.vo.AddressVo;
import org.apache.commons.math3.analysis.function.Add;
import org.springframework.web.bind.annotation.*;

/**
 * 收货地址(Address)表控制层
 *
 * @author WangFK
 * @since 2023-08-17 16:30:24
 */
@RestController
@RequestMapping("/store/address")
public class AddressController {
    /**
     * 服务对象
     */
    @Resource
    private AddressService addressService;
    @Resource
    private RedisCache redisCache;
    @Resource
    private MemberService memberService;



    @GetMapping("/getAddressListByMemberId")
    public AjaxResult getAddressListByMemberId(String memberId) {
        LambdaUpdateWrapper<Address> lqw = new LambdaUpdateWrapper<>();
        List<Address> list;
        if (ObjectUtil.isEmpty(memberId)) {
            lqw.eq(Address::getFlag, "1");
        } else {
            lqw.eq(Address::getMemberId, memberId);
        }
        list = addressService.list(lqw);
        if (ObjectUtil.isNotEmpty(list)) {
            list.stream().forEach(item -> {
                String addressName = item.getProvinceName() + "|"
                        + item.getCityName() + "|"
                        + item.getDistrictName() + "|"
                        + item.getDetail();
                item.setAddressName(addressName);
            });
        }
        return AjaxResult.success(list);
    }

    /**
     * 修改地址状态
     *
     * @param id
     * @param flag
     * @return
     */
    @GetMapping("/changeAddressFlag")
    public AjaxResult changeAddressFlag(String id, String flag) {
        Long memberId = addressService.getById(id).getMemberId();
        // 只能由一个默认
        if ("1".equalsIgnoreCase(flag)) {
            LambdaUpdateWrapper<Address> lqw = new LambdaUpdateWrapper<Address>()
                    .eq(Address::getMemberId, memberId)
                    .set(Address::getFlag, "0");
            addressService.update(lqw);
        }

        LambdaUpdateWrapper<Address> lqw = new LambdaUpdateWrapper<Address>()
                .eq(Address::getId, id)
                .set(Address::getFlag, flag);
        return addressService.update(lqw) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 获取全国地址
     *
     * @return
     */
    @GetMapping("/getAddressAndCode")
    public List<AddressVo> getAddressAndCode() {

        String key = "hibox:address:list";
        List<AddressVo> value = redisCache.getCacheList(key);
        if (ObjectUtil.isNotEmpty(value)) {
            return value;
        }
        String url = "https://www.mxnzp.com/api/address/list";
        HashMap<String, Object> params = new HashMap<>();
        params.put("app_id", "idgorwnnojpowkrl");
        params.put("app_secret", "wDKi9GfjUSlvAKb5ftYmV0IoB02PU5ys");

        AjaxResult result = JSONUtil.toBean(JSONUtil.toJsonStr(HttpUtil.get(url, params)), AjaxResult.class);
        List<Map> maps = JSONUtil.toList(result.get("data").toString(), Map.class);
        ArrayList<AddressVo> addresses = new ArrayList<>();
        maps.stream().forEach(item -> {
            AddressVo address = new AddressVo();
            ArrayList<AddressVo> addresses1 = new ArrayList<>();
            String code = item.get("code").toString();
            String name = item.get("name").toString();
            address.setCode(code);
            address.setName(name);
            List<Map> pchilds = Convert.toList(Map.class, item.get("pchilds"));
            pchilds.stream().forEach(item1 -> {
                AddressVo address1 = new AddressVo();
                ArrayList<AddressVo> addresses2 = new ArrayList<>();
                String code1 = item1.get("code").toString();
                String name1 = item1.get("name").toString();
                address1.setCode(code1);
                address1.setName(name1);
                List<Map> cchilds = Convert.toList(Map.class, item1.get("cchilds"));
                cchilds.stream().forEach(item2 -> {
                    AddressVo address2 = new AddressVo();
                    String code2 = item2.get("code").toString();
                    String name2 = item2.get("name").toString();
                    address2.setCode(code2);
                    address2.setName(name2);
                    addresses2.add(address2);
                });
                address1.setChildren(addresses2);
                addresses1.add(address1);
            });
            address.setChildren(addresses1);
            addresses.add(address);
        });
        redisCache.setCacheList(key, addresses);
        redisCache.expire(key, 12, TimeUnit.HOURS);
        return addresses;
    }

    @GetMapping("/list")
    public AjaxResult list(Long pageNum, Long pageSize, String search, String code, String label) {
        Page<Address> addressPage = new Page<>(pageNum, pageSize);
        LambdaUpdateWrapper<Address> lqw = new LambdaUpdateWrapper<Address>()
                .eq(ObjectUtil.isNotEmpty(code), Address::getAreaCode, code)
                .eq(ObjectUtil.isNotEmpty(label), Address::getLabel, label);
        if (ObjectUtil.isNotEmpty(search)) {
            lqw.like(Address::getConsignee, search).or()
                    .like(Address::getDetail, search).or()
                    .like(Address::getPhone, search);
        }
        addressPage = addressService.page(addressPage, lqw);
        List<Address> records = addressPage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return AjaxResult.success();
        }
        records.stream().forEach(item -> {
            Member byId = memberService.getById(item.getMemberId());
            if (ObjectUtil.isNotEmpty(byId)) {
                item.setMemberName(byId.getNickName());
            }
        });
        return AjaxResult.success()
                .put("rows", records)
                .put("total", addressPage.getTotal());
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public AjaxResult selectOne(@PathVariable Serializable id) {
        Address byId = addressService.getById(id);
        Member byId1 = memberService.getById(byId.getMemberId());
        byId.setMemberName(byId1.getNickName());
        return AjaxResult.success(byId);
    }

    /**
     * 新增数据
     *
     * @param address 实体对象
     * @return 新增结果
     */
    @PostMapping
    public AjaxResult insert(@RequestBody Address address) {
        if (ObjectUtil.isEmpty(address.getConsignee())) {
            return AjaxResult.error("收货人为空");
        }
        if (ObjectUtil.isEmpty(address.getProvinceName())) {
            return AjaxResult.error("请重新选择地址");
        }
        if (ObjectUtil.isEmpty(address.getLabel())) {
            return AjaxResult.error("请选择标签");
        }
        String phone = address.getPhone();
        if (ObjectUtil.isEmpty(phone)) {
            return AjaxResult.error("联系方式为空");
        }
        if (!PhoneUtil.isPhone(phone)) {
            return AjaxResult.error("手机号格式错误");
        }
        if ("1".equalsIgnoreCase(address.getFlag())) {
            LambdaUpdateWrapper<Address> lqw = new LambdaUpdateWrapper<Address>()
                    .eq(Address::getMemberId, address.getMemberId())
                    .set(Address::getFlag, "0");
            addressService.update(lqw);
        }
        if (ObjectUtil.isNotEmpty(address.getId())) {
            return update(address);
        }
        return addressService.save(address) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 修改数据
     *
     * @param address 实体对象
     * @return 修改结果
     */
    @PutMapping
    public AjaxResult update(@RequestBody Address address) {
        return addressService.updateById(address) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 删除数据
     *
     * @param id 主键结合
     * @return 删除结果
     */
    @DeleteMapping("{id}")
    public AjaxResult delete(@PathVariable String id) {
        List<String> split = StrUtil.split(id, ",");
        return addressService.removeBatchByIds(split) ? AjaxResult.success() : AjaxResult.error();
    }
}

